<?php
declare (strict_types=1);

namespace app\api\controller\v1;

use app\api\helpers\v1\traits\FileUpload;
use app\api\helpers\v1\traits\SearchDataForModel;
use app\api\model\v1\AdminLog;
use app\api\model\v1\AuthWxMenu;
use app\api\model\v1\AuthWxStudy;
use app\api\model\v1\CollectionTopic;
use app\api\model\v1\Learn;
use app\api\model\v1\LearnTopic;
use app\api\model\v1\MonthlyTest;
use app\api\model\v1\TopicExerciseLog;
use app\api\model\v1\TopicUserDay;
use app\api\model\v1\Unit;
use app\api\model\v1\Users;
use app\api\model\v1\WxMenu;
use app\BaseController;
use think\cache\driver\Redis;
use think\facade\Cache;
use think\facade\Db;
use think\Model;
use think\Request;

class Study extends BaseController
{
    use SearchDataForModel, FileUpload;

    /**
     * @User: 刘海龙
     * @Date: 2021/10/8
     * @Time: 15:50
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     * 数据源
     */
    public function getStudyList()
    {
        $limit = $this->request->param('limit', 10);
        $type = $this->request->param('type', 'page');
        if ($type === 'no_page') {
            $res = Learn::select();
        } else {
            $map = [];
            if ($this->request->has('learn_type') && !empty($this->request->param('learn_type'))) {
                $map[] = ['type', '=', $this->request->param('learn_type')];
            }
            $res = Learn::where($map)->paginate($limit)->each(function ($item, $key) {
                $item['type_name'] = Learn::$is_type[$item['type']];
                return $item;
            });

        }

        return $this->response($res);
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/24 10:07
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取微信权限
     */
    public function getStudyWxAuth()
    {
        $res = Learn::field('id,title')->where(['type' => Learn::TYPE_ONE])->select()->toArray();
        return $this->response($res);
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/10/8
     * @Time: 16:15
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     * 根据id获取对应的题目
     */
    public function getStudyTopicList()
    {
        $limit = $this->request->param('limit', 10);
        $learn_id = $this->request->param('learn_id', 0);
        $map[] = array('learn_id', '=', $learn_id);
        $res = $this->search(new LearnTopic(), $map, $limit, 'desc', ['option']);
        return $this->response($res);
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/10/8
     * @Time: 15:28
     * @return \think\response\Json
     * 导入学习考题
     */
    public function importStudyExcel()
    {
        if (!$this->request->file('file')) {
            return $this->response(501, '请选择上传文件');
        }
        $file = $this->request->file('file');
        $type = $this->request->param('type');
        $saveName = \think\facade\Filesystem::disk('public')->putFile('study_excel', $file);
        $path = app()->getRootPath() . 'public/storage/' . str_replace('\\', '/', $saveName);
        $returnData = $this->loadExcel($path);
        $data = $this->dataLearn($returnData);
        $is_bool = Learn::saveImportExcel($data, $this->request->uid, $type);

        if ($is_bool === 200) {
            //日志
            AdminLog::record('导入学习答题', $this->request->param(), $this->request->uid, $this->request->username);
            return $this->response();
        } else if ($is_bool === 403) {
            return $this->response(403, '未找到学习开始模版');
        } else {
            return $this->response(403, '导入失败');
        }
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/24 15:25
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取当前考试的题目
     */
    public function getExamStudyList()
    {
        $res = Learn::with(['topic'])->with(['admin'])->where(['type' => Learn::TYPE_TWO])->order('create_time desc')->select()->each(function ($item, $key) {
            $redis_key = 'monthly_test:' . $item['id'];
            // 排名
            $redis_arr = $this->redis->ZREVRANGE($redis_key, 0, 2, ['withscores' => true]);
            $new_arr = [];
            foreach ($redis_arr as $key => $v) {
                $new_arr[] = json_decode($key, true);
                foreach ($new_arr as $key1 => $value) {
                    $user = Users::findOrEmpty($value['id']);
                    if (!$user->isEmpty()) {
                        $new_arr[$key1]['head_img'] = $user->head_img;
                    }
                }
            }
            $item['rate'] = $new_arr; // 排名

            $topicData = $item['topic']->toArray();
            $score = 0;
            foreach ($topicData as $k => $v1) {
                $score += $v1['score'];
            }
            $item['total_score'] = $score;
            $item['total_topic'] = count($topicData);
            return $item;
        })->toArray();
        return $this->response($res);
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/24 9:22
     * @param $id
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException\
     * 删除
     */
    public function delStudy($id)
    {
        $res = Learn::with(['topic', 'option'])->find($id);
        if (is_null($res)) {
            return $this->response(404, '未找到资源');
        }
        $res->together(['topic', 'option'])->delete();
        return $this->response();
    }


    public function studyType()
    {
        $res = Learn::$is_type;
        return $this->response($res);
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/10/9
     * @Time: 8:57
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 根据id 获取对应的题目
     */
    public function getTopicList()
    {
        $id = $this->request->param('id', 0);//是否接收了id
        $map = [];
        if (intval($id) === 0) { //随机
            $ids = $this->getRedisTopicId(); //随机的时候
            $map[] = array('id', 'in', $ids);
        } else { //根据类型查找题目
            $res = Learn::find($id);
            if (is_null($res)) {
                return $this->response(403, '未找到相关题目');
            }
            $map[] = array('learn_id', '=', $id);
        }
        $topic_type = $this->request->param('topic_type', 1);//是否接收了id
        $map[] = array('topic_type', '=', $topic_type);
        $data = LearnTopic::field('id,topic_title as title,learn_id,learn_answer as answer,question_type as type,answer_explain,score')->with(['optionList' => function ($query) {
            $query->field('id,option_title as content,learn_topic_id');
            return $query;
        }, 'collectionTopic' => function ($q) {
            $q->where('collection_user_id', $this->request->wx_id);
        }])->where($map)->orderRaw('rand()')->select()->each(function ($item, $key) {
            $optionList_arr = $item['optionList']->toArray();
            if ($item['question_type'] !== TopicExerciseLog::TOPIC_FOUR && $item['question_type'] !== TopicExerciseLog::TOPIC_FIVE) {
                $change_option = TopicExerciseLog::changeOption(json_encode($optionList_arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), $optionList_arr[intval($item['answer']) - 1]['id'] . '', '');
                $item['new_answer'] = $change_option['new_answer'];//新正确答案
            }
            $item['userAnswer'] = "";
            $item['isAnswer'] = false;
            $item['isBtn'] = false; //是否点击了确定
            $item['collectionTopic'] === null ? $item['userFavor'] = false : $item['userFavor'] = true;
            return $item;
        })->toArray();
        return $this->response($data);
    }

    /**
     * @return \think\response\Json
     * 检测是否随机
     */
    public function checkUserMenuAuth()
    {
        $unit_id = $this->request->param('unit_id');
        $arr = [];
        if (intval($unit_id) !== 0) {
            $res = AuthWxStudy::findWxStduy(intval($unit_id), $this->search);
            foreach ($res as $key => $v) {
                $arr[] = $v['learn_id'];
            }
        }
        if (empty($arr)) {
            $arr = [0];
        }
        return $this->response($arr);
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/21 11:06
     * @return mixed|string
     * 随机生成10个id
     */
    public function getRedisTopicId()
    {
        //1.redis key值 用户名+年月 进行范围匹配
        $redis_key = 'daily:' . $this->request->wx_id . ':' . date('Y') . ':' . date('m');
        $res = LearnTopic::where(['topic_type' => Learn::TYPE_ONE])->whereBetweenTime('create_time', '2022-09-01', '2022-12-30')->order('create_time desc')->column('id');
        //3.从数据库取出题目id
        //4.取出当前前缀key所有的key
        $redis_key_arr = $this->redis->keys($redis_key . '*');
        //2.判断redis key值是否存在
        if (!empty($redis_key_arr)) {
            $learnTopic_ids_redis = '';
            //3.1如果redis key存在 数据库取出的id 去除redis中的
            foreach ($redis_key_arr as $key => $value) {
                $learnTopic_ids_redis .= $this->redis->get($value) . ',';
            }
            //取出的keys 转为数组 进行差集比较
            $learnTopic_ids_redis_arr = explode(',', rtrim($learnTopic_ids_redis, ','));
            //差集比较
            $res = array_diff($res, $learnTopic_ids_redis_arr);
        }
        //今天的key值
        $today_redis_key = $redis_key . ':' . date('d') . ':' . date('s');
        //判断当天的日期是否存在redis中  不存在写入  存在的话直接读取
        if (!$this->redis->has($today_redis_key)) {
            //从数据中随机抽取10个
            $newArr = array_rand($res, 10);
            //随机取值转为字符串
            $str = '';
            foreach ($newArr as $key => $value) {
                $str .= $res[$value] . ',';
            }
            $learnTopic_ids = rtrim($str, ',');
            $this->redis->set($today_redis_key, $learnTopic_ids, 60);
        } else {
            //直接从redis中进行获取
            $learnTopic_ids = $this->redis->get($today_redis_key);
        }
        return $learnTopic_ids;
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/10/9
     * @Time: 9:52
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 收藏
     */
    public function collectionTopic()
    {
        $data = $this->request->param();
        $topic_id = intval($data['topic_id']);
        $date_of = $data['date_of'];
        $res = CollectionTopic::where(['learn_topic_id' => $topic_id, 'collection_user_id' => $this->request->wx_id])->find();
        if (!is_null($res) && intval($data['is_collection']) !== 0) {
            return $this->response(403, '题目已经收藏,无需重复收藏');
        }
        if (intval($data['is_collection']) === 0) { //取消收藏
            CollectionTopic::destroy(function ($query) use ($topic_id, $date_of) {
                $query->where(['learn_topic_id' => $topic_id, 'collection_user_id' => $this->request->wx_id, 'date_of' => $date_of])->delete();
            }, true);
            $return_arr = [
                'type' => 'delete'
            ];
        } else { //收藏
            CollectionTopic::create([
                'learn_topic_id' => $data['topic_id'],
                'collection_user_id' => $this->request->wx_id,
                'date_of' => $date_of
            ]);
            $return_arr = [
                'type' => 'create'
            ];
        }
        return $this->response($return_arr);
    }


    public function checkTopicUserDay($date_of)
    {


    }


    /**
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 保存练习
     */
    public function saveTopic()
    {
        $learn_type = $this->request->param('learn_type');
        //题型：1判断题，2单选题，3多选题，4填空题，5问答题
        $data = $this->request->except(['version']);
        $data['date_of'] = date("Y-m-d");
        //转换数组入库
        $logData = $this->todayStudy($data);
        //获取答题结果
        $examResult = $this->examResult($logData, $data);
        $unit = Unit::find($data['unit_id']);
        if (is_null($unit)) {
            return $this->response(404, '单位不存在');
        }
        if (intval($learn_type) === Learn::TYPE_TWO) { //考试状态
            $redis_key = 'monthly_test:' . $data['learn_id'];
            //考试结果入库
            //判断当前人在本月答题多少次 限制3次不能提交
            $monthCount = MonthlyTest::where(['user_id' => $this->request->wx_id, 'learn_id' => $data['learn_id']])->whereMonth('create_time')->count();
            if ($monthCount >= 3) {
                return $this->response(404, '本月最多只能提交3次考试');
            }
            $topic_user_day_id = MonthlyTest::create($examResult)->id;
        } else { //每日练习 入库
            //记录每次答题的结果
            $redis_key = 'topic_user_day:' . $data['date_of'] . ':' . $this->request->wx_id;
            $topic_user_day_id = TopicUserDay::create($examResult)->id;
        }
        //答题记录 入库
        foreach ($logData as $key => $v) {
            $v['topic_user_day_id'] = $topic_user_day_id;
            TopicExerciseLog::create($v);
        }
        //把$topic_user_day_id 添加到结果集中
        $examResult['topic_user_day_id'] = $topic_user_day_id;
        //redis 排名
        //新增到redis中 做排名
        $timestamp = mktime($data['hour'], $data['minute'], $data['second']);
        $score = $examResult['correct'] . '.' . (time() - $timestamp);
        $value = [
            'id' => $this->request->wx_id,
            'name' => $this->request->wx_user_name,
            'topic_user_day_id' => $topic_user_day_id,
            'learn_id' => $data['learn_id'],
            'score' => $examResult['correct'],
            'duration' => $examResult['duration'],
            'unit_title' => $unit['unit_title'] ?? '',
            'unit_id' => $examResult['unit_id'],
        ];
        //新增到redis中
        $this->redis->zadd($redis_key, $score, json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
        //返回结果集
        return $this->response($examResult);
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/5/12 13:38
     * @param $logData
     * @param $learn_id
     * @param $date_of
     * @param $unit_id
     * @param $unit_title
     * @return array
     * 考试结果
     */
    public function examResult($logData, $data)
    {
        $duration = $data['hour'] . '时' . $data['minute'] . '分' . $data['second'] . '秒';
        $correct = 0; //答对
        $error = 0; //答错
        $score = 0; //分值
        foreach ($logData as $key => $v) {
            if (intval($v['is_error']) == 0) {
                //题型：1判断题，2单选题，3多选题，4填空题，5问答题
                $correct++;
                $score += $v['score'];
            } else {
                $error++;
            }
        }
        //时分秒转换成具体的总秒数
        $total_seconds = turnSecond($duration);
        if (count($logData) > 0) {
            $correct_rate = round(($correct / count($logData)) * 100, 2);
        } else {
            $correct_rate = 0;
        }
        $new_data = [
            'is_admin' => $data['is_admin'] ?? 0,
            'user_id' => $this->request->wx_id,
            'learn_id' => $data['learn_id'],
            'correct' => $correct,
            'error' => $error,
            'correct_rate' => $correct_rate,
            'duration' => $duration,
            'total_seconds' => $total_seconds,
            'score' => $score, //得分
            'date_of' => $data['date_of'],
            'unit_id' => $data['unit_id'],
            'total' => count($logData) ?? 0,//总数
            'total_score' => count($logData) ?? 0, //总分
        ];
        return $new_data;
    }


    public function examMonthTest_1($logData, $learn_id, $date_of, $unit_id, $unit_title)
    {

        $find_learn = Learn::find($learn_id);
        $map = [
            'user_id' => $this->request->wx_id,
            'learn_id' => $learn_id,
            'date_of' => $date_of
        ];
        $is_find = MonthlyTest::where($map)->findOrEmpty();
        if (!$is_find->isEmpty()) {
            return ['code' => 404, 'msg' => '您今天已经提交了', 'data' => []];
        }
        $duration = $this->request->param('hour') . '时' . $this->request->param('minute') . '分' . $this->request->param('second') . '秒';
        $timestamp = mktime($this->request->param('hour'), $this->request->param('minute'), $this->request->param('second'));
        $correct = 0; //答对
        $error = 0; //答错
        foreach ($logData as $key => $v) {
            if (intval($v['is_error']) == 0) {
                $correct += $v['score'];
            } else {
                $error++;
            }
        }
        //时分秒转换成具体的总秒数
        $total_seconds = turnSecond($duration);
        $new_data = [
            'user_id' => $this->request->wx_id,
            'learn_id' => $learn_id,
            'correct' => $correct,
            'error' => $error,
            'correct_rate' => $correct / 50,
            'duration' => $duration,
            'total_seconds' => $total_seconds,
            'score' => $correct, //得分
            'date_of' => $date_of,
            'unit_id' => $unit_id,
            'total' => count($logData) ?? 0,//总数
            'total_score' => count($logData) ?? 0, //总分
            'learn_name' => $find_learn->title ?? ''
        ];
        $monthly_test = MonthlyTest::create($new_data);
        //新增到redis中 做排名
        $key = 'monthly_test:' . $learn_id;
        $score = $correct . '.' . (time() - $timestamp);
        $value = [
            'id' => $this->request->wx_id,
            'name' => $this->request->wx_user_name,
            'monthly_test_id' => $monthly_test->id,
            'score' => $correct,
            'duration' => $duration,
            'unit_title' => $unit_title,
            'unit_id' => $unit_id
        ];
        $this->redis->zadd($key, $score, json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
        return ['code' => 200, 'data' => $new_data];
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/5/12 13:40
     * @param $data
     * @return array
     * 每日练习
     */
    public function todayStudy($data)
    {
        $logData = [];
        foreach ($data['data'] as $key => $value) {
            switch ($value['type']) {
                case 1: //判断题
                case 2://单选题
                    $optionListIndex = $value['answer'] - 1; //获取答案的索引
                    $answer_id = $value['optionList'][$optionListIndex]['id'];
                    $userAnswers = $value['userAnswer'];
                    if (intval($userAnswers) !== $answer_id) {
                        $is_error = 1; //错误
                    } else {
                        $is_error = 0; //正确
                    }
                    break;
                case 3: //多选题
                    $userAnswers = rtrim($value['userAnswer'], ',');
                    $answer_arr = explode(',', $value['answer']); //正确答案
                    $answer_ids = '';
                    //把索引转换为id字符串
                    foreach ($answer_arr as $k => $v) {
                        $answer_arr_key = intval($v) - 1;
                        $answer_ids .= $value['optionList'][$answer_arr_key]['id'] . ',';
                    }
                    $answer_id = rtrim($answer_ids, ',');
                    if ($userAnswers !== $answer_id) {
                        $is_error = 1; //错误
                    } else {
                        $is_error = 0; //正确
                    }
                    break;
                case 4: //4填空题
                case 5: //5问答题
                default: //其他
                    $is_error = 0; //正确
                    $userAnswers = $value['userAnswers'];
                    $answer_id = $value['answer'];
                    break;
            }
            $logData[] = [
                'learn_id' => $value['learn_id'],
                'title' => $value['title'],
                'learn_topic_id' => $value['id'],
                'answer' => $answer_id,
                'type' => $value['type'],
                'answer_explain' => $value['answer_explain'],
                'option' => json_encode($value['optionList'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
                'user_answer' => $userAnswers,
                'user_favor' => $value['userFavor'] === false ? 0 : 1,
                'show_answer' => $value['showAnswer'] === false ? 0 : 1,
                'is_error' => $is_error,
                'exercise_user_id' => $this->request->wx_id,
                'date_of' => $data['date_of'],
                'learn_type' => $data['learn_type'],
                'score' => $value['score'] ?? 0
            ];
        }
        return $logData;
    }

    public function todayStudy1($data)
    {
        if (intval($data['learn_type']) === Learn::TYPE_ONE) {
            $map = [
                'user_id' => $this->request->wx_id,
                'date_of' => $data['date_of'],
                'unit_id' => $data['unit_id'],
            ];
            $is_find = TopicUserDay::where($map)->findOrEmpty();
//            if (!$is_find->isEmpty()) {
//                return ['code' => 404, 'data' => []];
//            }
            $is_find->save($map);
            $topic_user_day_id = $is_find->id;
        } else {
            $topic_user_day_id = 0;
        }

        $logData = [];
        foreach ($data['data'] as $key => $value) {
            switch ($value['type']) {
                case 1: //判断题
                case 2://单选题
                    $optionListIndex = $value['answer'] - 1; //获取答案的索引
                    $answer_id = $value['optionList'][$optionListIndex]['id'];
                    $userAnswers = $value['userAnswer'];
                    if (intval($userAnswers) !== $answer_id) {
                        $is_error = 1; //错误
                    } else {
                        $is_error = 0; //正确
                    }
                    break;
                case 3: //多选题
                    $userAnswers = rtrim($value['userAnswer'], ',');
                    $answer_arr = explode(',', $value['answer']); //正确答案
                    $answer_ids = '';
                    //把索引转换为id字符串
                    foreach ($answer_arr as $k => $v) {
                        $answer_arr_key = intval($v) - 1;
                        $answer_ids .= $value['optionList'][$answer_arr_key]['id'] . ',';
                    }
                    $answer_id = rtrim($answer_ids, ',');
                    if ($userAnswers !== $answer_id) {
                        $is_error = 1; //错误
                    } else {
                        $is_error = 0; //正确
                    }
                    break;
                case 4: //4填空题
                case 5: //5问答题
                default: //其他
                    $is_error = 0; //正确
                    $userAnswers = $value['userAnswers'];
                    $answer_id = $value['answer'];
                    break;
            }
            $logData[] = [
                'learn_id' => $value['learn_id'],
                'title' => $value['title'],
                'learn_topic_id' => $value['id'],
                'answer' => $answer_id,
                'type' => $value['type'],
                'answer_explain' => $value['answer_explain'],
                'option' => json_encode($value['optionList'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
                'user_answer' => $userAnswers,
                'user_favor' => $value['userFavor'] === false ? 0 : 1,
                'show_answer' => $value['showAnswer'] === false ? 0 : 1,
                'is_error' => $is_error,
                'exercise_user_id' => $this->request->wx_id,
                'date_of' => $data['date_of'],
                'topic_user_day_id' => $topic_user_day_id,
            ];
        }
        return ['code' => 200, 'data' => $logData];
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/5/12 10:53
     * @return \think\response\Json
     * 保存单一练习题目
     */
    public function saveSingleTopic()
    {
        $data = $this->request->param();
        $res = $this->fzNewArr($data);
        TopicExerciseLog::create($res);
        $result = [
            'error' =>
                [$data['subjectIndex'] => $res['is_error']]

        ];
        return $this->response($result);
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/5/12 10:50
     * @param $data
     * @return array
     * 封装方法 -- 练习入库
     */
    public function fzNewArr($data)
    {
        switch ($data['data']['type']) {
            case 1: //判断题
            case 2://单选题
                $optionListIndex = $data['data']['answer'] - 1; //获取答案的索引
                $answer_id = $data['data']['optionList'][$optionListIndex]['id'];
                $userAnswers = $data['data']['userAnswer'];
                if (intval($userAnswers) !== $answer_id) {
                    $is_error = 1; //错误
                } else {
                    $is_error = 0; //正确
                }
                break;
            case 3: //多选题
                $userAnswers = rtrim($data['data']['userAnswer'], ',');
                $answer_arr = explode(',', $data['data']['answer']); //正确答案
                $answer_ids = '';
                //把索引转换为id字符串
                foreach ($answer_arr as $k => $v) {
                    $answer_arr_key = intval($v) - 1;
                    $answer_ids .= $data['data']['optionList'][$answer_arr_key]['id'] . ',';
                }
                $answer_id = rtrim($answer_ids, ',');
                if ($userAnswers !== $answer_id) {
                    $is_error = 1; //错误
                } else {
                    $is_error = 0; //正确
                }
                break;
            case 4: //4填空题
            case 5: //5问答题
            default: //其他
                $is_error = 0; //正确
                $userAnswers = $data['data']['userAnswers'];
                $answer_id = $data['data']['answer'];
                break;
        }
        $logData = [
            'learn_id' => $data['data']['learn_id'],
            'title' => $data['data']['title'],
            'learn_topic_id' => $data['data']['id'],
            'answer' => $answer_id,
            'type' => $data['data']['type'],
            'answer_explain' => $data['data']['answer_explain'],
            'option' => json_encode($data['data']['optionList'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
            'user_answer' => $userAnswers,
            'user_favor' => $data['data']['userFavor'] === false ? 0 : 1,
            'show_answer' => $data['data']['showAnswer'] === false ? 0 : 1,
            'is_error' => $is_error,
            'exercise_user_id' => $this->request->wx_id,
            'date_of' => $data['date_of']
        ];
        return $logData;
    }


    /**
     * @User: 刘海龙
     * @Date: 2021/10/14
     * @Time: 18:11
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 数据列表
     */
    public function getTopicExerciseLog()
    {
        $data = $this->request->param();

        if (intval($data['idx']) === 0) {
            //答题记录
            $res = TopicExerciseLog::with(['option'])->where(['exercise_user_id' => $this->request->wx_id, 'date_of' => $data['date']])->select()->each(function ($item, $key) {
                if ($item['question_type'] !== TopicExerciseLog::TOPIC_FOUR && $item['question_type'] !== TopicExerciseLog::TOPIC_FIVE) {
                    $change_option = TopicExerciseLog::changeOption($item['option'], $item['answer'], $item['user_answer']);
                    $item['new_answer'] = $change_option['new_answer'];//新正确答案
                    $item['new_my_answer'] = $change_option['new_my_answer']; //新我的答案
                    return $item;
                }
            })->toArray();
        } else if (intval($data['idx']) === 1) {
            //错题记录
            $res = TopicExerciseLog::with(['option'])->where(['exercise_user_id' => $this->request->wx_id, 'date_of' => $data['date'], 'is_error' => 1])->select()->each(function ($item, $key) {
                if ($item['question_type'] !== TopicExerciseLog::TOPIC_FOUR && $item['question_type'] !== TopicExerciseLog::TOPIC_FIVE) {
                    $change_option = TopicExerciseLog::changeOption($item['option'], $item['answer'], $item['user_answer']);
                    $item['new_answer'] = $change_option['new_answer'];//新正确答案
                    $item['new_my_answer'] = $change_option['new_my_answer']; //新我的答案
                    return $item;
                }
            })->toArray();
        } else if (intval($data['idx']) === 2) {
            //收藏
            $res = CollectionTopic::with(['topic.option'])->where(['collection_user_id' => $this->request->wx_id, 'date_of' => $data['date']])->select()->each(function ($item, $key) {
                $data = ($item->toArray());
                $answer = explode(',', $item['topic']['learn_answer']);
                $ids = '';
                foreach ($answer as $k => $v) {
                    $index = intval($v) - 1;
                    $ids .= $item['topic']['option'][$index]['id'] . ',';
                }
                $item['topic']['new_answer'] = rtrim($ids, ',');
                if ($data['topic']['question_type'] !== TopicExerciseLog::TOPIC_FOUR && $data['topic']['question_type'] !== TopicExerciseLog::TOPIC_FIVE) {
                    $change_option = TopicExerciseLog::changeOption(json_encode($data['topic']['option'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), rtrim($ids, ','), '');
                    $item['topic']['new_answer'] = $change_option['new_answer'];//新正确答案
                }
                return $item;
            })->toArray();

        } else {
            //其他
            $res = [];
        }
        if (!empty($res)) {
            return $this->response($res);
        } else {
            return json(['code' => 400, 'data' => []]);
        }
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/26 15:34
     * @return \think\response\Json
     * 按天统计 --- 答题
     */
    public function getDayStatisticsList()
    {
        $limit = $this->request->param('limit', 10);
        $activeIndex = $this->request->param('activeIndex', 0);
        $where = [];
        //pc端
        if ($this->request->has('unit_id') && !empty($this->request->param('unit_id'))) {
            $unit_parent_arr = $this->request->param('unit_id');
            $children = $this->search->getChildrenIds(intval(end($unit_parent_arr)), true);
            $where[] = ['unit_id', 'in', $children];
        }
        //wx端
        if ($this->request->has('unit_wx_id') && !empty($this->request->param('unit_wx_id'))) {
            $unit_parent_arr = $this->request->param('unit_wx_id');
            $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
            $where[] = ['unit_id', 'in', $children];
        }
        //微信
        if ($this->request->has('date_of') && !empty($this->request->param('date_of'))) {
            $where[] = ['date_of', '=', $this->request->param('date_of')];
        }
        //pc
        if ($this->request->has('user_id') && !empty($this->request->param('user_id'))) {
            $where[] = ['user_id', '=', $this->request->param('user_id')];
        }
        //pc
        if ($this->request->has('date_range') && !empty($this->request->param('date_range'))) {
            $date_range = $this->request->param('date_range');
            $where[] = ['date_of', 'between', "$date_range[0],$date_range[1]"];
        }

        $where[] = ['is_admin', '=', 0];
        if (intval($activeIndex) == 0) {
            //withCount(['topic' => function ($query2, &$alias2) {
            //                    $query2->where(['is_error' => 1]);
            //                    $alias2 = 'error_count';
            //                    return $query2;
            //                }])
            //                ->withCount(['topic' => function ($query3, &$alias3) {
            //                    $query3->where(['is_error' => 0]);
            //                    $alias3 = 'correct_count';
            //                    return $query3;
            //                }])
            //                ->


            $res = TopicUserDay::where($where)->with(['topic','removeUser', 'unit'])->order('create_time','desc')
                ->paginate($limit)->each(function ($item, $key) {
                    $unit_parent_arr = $this->search->getParents($item['unit_id']);
                    $unit_parent_str = "";
                    foreach ($unit_parent_arr as $key => $value) {
                        $unit_parent_str .= $value['unit_title'] . '-';
                    }
                    $item['username'] = $item['user']['username'] ?? '';
                    $item['unit_title'] = $item['unit']['unit_title'] ?? '未匹配';
                    $item['unit_parent'] = rtrim($unit_parent_str, '-') ?? '顶级';
                    return $item;
                });
        } else {
            //wx端
            if ($this->request->has('unit_wx_id') && !empty($this->request->param('unit_wx_id'))) {
                $unit_parent_arr = $this->request->param('unit_wx_id');
                $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
                $topicUserDay = TopicUserDay::where($where)->column('unit_id');
                $arr_diff = array_diff($children, $topicUserDay);
                $map[] = ['id', 'in', array_values($arr_diff)];
            }
            $map[] = array('level', '=', 3);
            $map[] = array('attribute', '<>', 3);
            $res = Unit::with(['topicUserDay' => function ($q1) use ($where) {
                return $q1->where($where);
            }])->where($map)->paginate($limit)->each(function ($item, $key) {
                $unit_parent_arr = $this->search->getParents($item['id']);
                $unit_parent_str = "";
                foreach ($unit_parent_arr as $key => $value) {
                    $unit_parent_str .= $value['unit_title'] . '-';
                }
                $item['date_of'] = $this->request->param('date_of') ?? '';
                $item['username'] = '未知';
                $item['topic_count'] = 0;
                $item['correct_count'] = 0;
                $item['error_count'] = 0;
                $item['unit_parent'] = rtrim($unit_parent_str, '-');
                return $item;
            });
        }
        return $this->response($res);


    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/27 9:11
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     * 未上传单位
     */
    public function notUploadUnit()
    {
        $limit = $this->request->param('limit', 10);
        $type = $this->request->param('type', 1);
        $where = [];
        $map = [];
        if ($this->request->has('date_range') && !empty($this->request->param('date_range'))) {
            $date_range = $this->request->param('date_range');
            $where[] = ['date_of', 'between', "$date_range[0],$date_range[1]"];
        }
        //wx端
        if ($this->request->has('unit_wx_id') && !empty($this->request->param('unit_wx_id'))) {
            $unit_parent_arr = $this->request->param('unit_wx_id');
            $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
            $map[] = ['id', 'in', $children];
        }
        //微信
        if ($this->request->has('date_of') && !empty($this->request->param('date_of'))) {
            $where[] = ['date_of', '=', $this->request->param('date_of')];
        }
//        $map[] = array('level', '=', 3);
//        $map[] = array('attribute', '<>', 3);
        $map[] = array('is_admin', '=', 0);
        $map[] = array('wx_role_id', '<>', 2);
        if (intval($type) === 1) {
            $res = TopicUserDay::where($where)->where('is_admin',0)->column('unit_id');
        } else {
            $res = MonthlyTest::where($where)->where('is_admin',0)->column('unit_id');
        }
        $new_arr = Users::field('id,unit_id,username')->with(['removeUnit'])->whereNotIn('unit_id', array_values(array_unique($res)))->where($map)->paginate($limit);
        return $this->response($new_arr);
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/7/1 16:51
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 月考 表格统计
     */
    public function monthlyCheck()
    {
        $unit_id = $this->request->param('unit_id', 230);
        $nowMonth = $this->request->param('nowMonth', date('m'));

        $monthData = MonthlyTest::$month;
        $headers[] = array('label' => '网点名称', 'key' => 'unit_title');
        $headers[] = array('label' => '网点总数', 'key' => 'count');
        $headers[] = array('label' => '已考总数', 'key' => 'tested_total');
        $res = Unit::field('id,unit_title,level')->where('pid', $unit_id)->select()->each(function ($item, $key) use ($nowMonth) {
            $children = $this->search->getChildrenIds($item['id'], true);
            $count_children = $this->search->getChildrenIds($item['id'], false); //不包含自己
            $tested_total = $this->monthlyCheckTj($children, $nowMonth);
            if ($item['level'] === 3){
                $item['count'] = count($children);
            }else{
                $item['count'] = count($count_children);
            }
            $item['tested_total'] = $tested_total === 0 ? 0 : count($tested_total);
            $score = 0; //得分
            $total_score = 0; //总分
            if ($tested_total !== 0){
                foreach ($tested_total as $key=>$value){
                    $score +=$value['score'];
                    $total_score += 100;
                }
            }
            //准确率
            if ($total_score !== 0){
                $item['rate'] = round(($score / $total_score) * 100, 2);
            }else{
                $item['rate'] = 0;
            }
            $item['score'] = $score;
            $item['total_score'] = $total_score;
            return $item;
        })->toArray();
        $new_data = [
            'month' => $monthData,
            'headers' => $headers,
            'contents' => $res
        ];
        return $this->response($new_data);
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/7/1 16:58
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 考试详情
     */
    public function personMonthlyDetail(){
        $unit_id = $this->request->param('unit_id', 0);
        $nowMonth = $this->request->param('nowMonth', date('m'));

        if (intval($nowMonth) < 10) {
            $nowMonth = '0' . $nowMonth;
        }
        $lean = Learn::whereMonth('create_time', date('Y') . '-' . $nowMonth)->findOrEmpty();
        if ($lean->isEmpty()){
            return $this->response(404,'暂未找到该答题信息');
        }
        $unit = Unit::findOrEmpty($unit_id);
        if ($unit->isEmpty()) {
           return $this->response(404,'暂未找到该网点');
        }
        $res = MonthlyTest::with(['removeUser','unit'])->withCount(['topic'])->where('unit_id',$unit_id)->where('learn_id',$lean->id)->select();
        return $this->response($res);
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/7/4 9:37
     * @param $children
     * @param $nowMonth
     * @return int|\think\response\Json
     * 统计月考数
     */
    public function monthlyCheckTj($children, $nowMonth)
    {
        $lean = Learn::where('month',$nowMonth)->findOrEmpty();
        if ($lean->isEmpty()){
            $res = 0;
        }else{
            $subQuery = Db::table('monthly_test')
                ->where('learn_id',$lean->id)
                ->where('is_admin', 0) //不为管理员的时候
                ->where('unit_id', 'in', $children)
                ->order('error asc')
                ->limit(1000000)
                ->buildSql();
            $res = Db::table($subQuery . ' a')
                ->group('a.unit_id') //user_id
                ->order('a.id desc')
                ->select()->toArray();
        }
        return $res;
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/4/26 15:34
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     * 按月统计
     */
    public function getMonthStatisticsList()
    {
        $limit = $this->request->param('limit', 10);
        $activeIndex = $this->request->param('activeIndex', 0);
        $where = [];
        //pc端
        if ($this->request->has('unit_id') && !empty($this->request->param('unit_id'))) {
            $unit_parent_arr = $this->request->param('unit_id');
            $children = $this->search->getChildrenIds(intval(end($unit_parent_arr)), true);
            $where[] = ['unit_id', 'in', $children];
        }
        //wx端
        if ($this->request->has('unit_wx_id') && !empty($this->request->param('unit_wx_id'))) {
            $unit_parent_arr = $this->request->param('unit_wx_id');
            $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
            $where[] = ['unit_id', 'in', $children];
        }
        //微信
        if ($this->request->has('date_of') && !empty($this->request->param('date_of'))) {
            $where[] = ['date_of', '=', $this->request->param('date_of')];
        }
        //pc
        if ($this->request->has('user_id') && !empty($this->request->param('user_id'))) {
            $where[] = ['user_id', '=', $this->request->param('user_id')];
        }
        //pc
        if ($this->request->has('date_range') && !empty($this->request->param('date_range'))) {
            $date_range = $this->request->param('date_range');
            $where[] = ['date_of', 'between', "$date_range[0],$date_range[1]"];
        }
        if (intval($activeIndex) == 0) {
            $res = MonthlyTest::with(['user', 'unit', 'learn'])->where($where)->where('is_admin',0)->order('create_time desc ')->paginate($limit)->each(function ($item, $key) {
                $unit_parent_arr = $this->search->getParents($item['unit_id']);
                $unit_parent_str = "";
                foreach ($unit_parent_arr as $key => $value) {
                    $unit_parent_str .= $value['unit_title'] . '-';
                }
                $item['username'] = $item['user']['username'] ?? '';
                $item['unit_title'] = $item['unit']['unit_title'] ?? '';
                $item['unit_parent'] = rtrim($unit_parent_str, '-');
                $item['topic_count'] = ($item['correct'] + $item['error']) ?? 0;
                return $item;
            });

        } else {
            //wx端
            if ($this->request->has('unit_wx_id') && !empty($this->request->param('unit_wx_id'))) {
                $unit_parent_arr = $this->request->param('unit_wx_id');
                $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
                $topicUserDay = MonthlyTest::where($where)->column('unit_id');
                $arr_diff = array_diff($children, $topicUserDay);
                $map[] = ['id', 'in', array_values($arr_diff)];
            }

            $map[] = array('level', '=', 3);
            $map[] = array('attribute', '<>', 3);
            $res = Unit::with(['monthlyTest' => function ($q1) use ($where) {
                return $q1->where($where);
            }])->where($map)->paginate($limit)->each(function ($item, $key) {
                $unit_parent_arr = $this->search->getParents($item['id']);
                $unit_parent_str = "";
                foreach ($unit_parent_arr as $key => $value) {
                    $unit_parent_str .= $value['unit_title'] . '-';
                }
                $item['date_of'] = $this->request->param('date_of') ?? '';
                $item['username'] = '未知';
                $item['topic_count'] = 0;
                $item['score'] = 0;
                $item['correct'] = 0;
                $item['error'] = 0;
                $item['correct_rate'] = 0;
                $item['duration'] = 0;
                $item['unit_parent'] = rtrim($unit_parent_str, '-');
                return $item;
            });
        }
        return $this->response($res);

//        $limit = $this->request->param('limit', 10);
//        $where = [];
//        if ($this->request->has('unit_id') && !empty($this->request->param('unit_id'))) {
//            $unit_parent_arr = $this->request->param('unit_id');
//            $children = $this->search->getChildrenIds(intval(end($unit_parent_arr)), true);
//            $where[] = ['unit_id', 'in', $children];
//        }
////        if ($this->request->has('date_of') && !empty($this->request->param('date_of'))) {
////            $where[] = ['date_of', '=', $this->request->param('date_of')];
////        }
//        if ($this->request->has('user_id') && !empty($this->request->param('user_id'))) {
//            $where[] = ['user_id', '=', $this->request->param('user_id')];
//        }
//        if ($this->request->has('date_range') && !empty($this->request->param('date_range'))) {
//            $date_range = $this->request->param('date_range');
//            $where[] = ['date_of', 'between', "$date_range[0],$date_range[1]"];
//
//        }
//        $res = MonthlyTest::with(['user', 'unit', 'learn'])->where($where)->paginate($limit)->each(function ($item, $key) {
//            $unit_parent_arr = $this->search->getParents($item['unit_id']);
//            $unit_parent_str = "";
//            foreach ($unit_parent_arr as $key => $value) {
//                $unit_parent_str .= $value['unit_title'] . '-';
//            }
//            $item['unit_parent'] = rtrim($unit_parent_str, '-');
//            $item['topic_count'] = ($item['correct'] + $item['error']) ?? 0;
//            return $item;
//        });
//        return $this->response($res);
    }


    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/7/1 15:04
     * @return \think\response\Json
     * 微信端首页统计--废弃
     */
    public function homeDayCount()
    {
        $where = [];
        $map = [];
        //wx端
        if ($this->request->has('unit_id') && !empty($this->request->param('unit_id'))) {
            $unit_parent_arr = $this->request->param('unit_id');
            $children = $this->search->getChildrenIds(intval($unit_parent_arr), true);
            $map[] = ['unit_id', 'in', $children];
            $where[] = ['id', 'in', $children];
        }

        $redis_key = "real_time_statistics:" . $this->request->param('unit_id');
        $redis_arr = $this->redis->has($redis_key);
        if (!$redis_arr) {
            //网点总数
            $res = Unit::where($where)->where('level', '=', 3)->count();
            //今日已答题
            $day_count = TopicUserDay::where($map)->whereDay('create_time')->count();
            //累计答题
            $cumulative_count = TopicUserDay::where($map)->count();
            //本月考试统计
            $month_count = MonthlyTest::where($map)->whereMonth('create_time')->count();
            //累计月考
            $monthlyTestCount = MonthlyTest::where($map)->count();

            $new_arr['unit_count'] = $res;
            $new_arr['day_count'] = $day_count;
            $new_arr['day_no_count'] = $res - $day_count;   //今日未答题
            $new_arr['cumulative_count'] = $cumulative_count;
            $new_arr['monthlyTestCount'] = $monthlyTestCount;
            $new_arr['month_count'] = $month_count;
            $new_arr['data'] = $this->dtList($map);
            $this->redis->set($redis_key, json_encode($new_arr, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
        }
        //直接从redis中进行获取
        $learnTopic_ids = $this->redis->get($redis_key);
        return $this->response(json_decode($learnTopic_ids, true));
    }

    /**
     * Notes:
     * User: liuhailong
     * DateTime: 2022/7/1 15:04
     * @param $map
     * @return array|array[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 废弃
     */
    public function dtList($map)
    {
        //答题单位列表
        $unit_data = TopicUserDay::withCount(['topic'])
            ->withCount(['topic' => function ($query2, &$alias2) {
                $query2->where(['is_error' => 1]);
                $alias2 = 'error_count';
                return $query2;
            }])
            ->withCount(['topic' => function ($query3, &$alias3) {
                $query3->where(['is_error' => 0]);
                $alias3 = 'correct_count';
                return $query3;
            }])
            ->where($map)->whereDay('create_time')->with(['user', 'unit'])
            ->limit(10)->select()->each(function ($item, $key) {
                $unit_parent_arr = $this->search->getParents($item['unit_id']);
                $unit_parent_str = "";
                foreach ($unit_parent_arr as $key => $value) {
                    $unit_parent_str .= $value['unit_title'] . '-';
                }
                $item['username'] = $item['user']['username'] ?? '';
                $item['unit_title'] = $item['unit']['unit_title'] ?? '未匹配';
                $item['unit_parent'] = rtrim($unit_parent_str, '-');
                return $item;
            })->toArray();
        if (empty($unit_data)) {
            $unit_data = [
                'data' => [
                    'topic_count' => 0,
                    'username' => '',
                    'unit_title' => '暂无数据',
                    'unit_parent' => '',
                    'error_count' => 0,
                    'correct_count' => 0,
                ]
            ];
        }
        return $unit_data;
    }

}
